#ifndef GTL_GAME_UTILS_HEADER_GUARD
#define GTL_GAME_UTILS_HEADER_GUARD

#include "gtlCompilerSpecific.h"
#include "external/pstdint.h"

namespace GTL
{
  namespace GameUtils
  {
    /**
    How to use:

    class JakasClass : public Thinker<JakasClass>
    {
    public:
      void Step1(int t, void*)
      {
        printf("Step 1\n");
        SetThink(t+1000, &JakasClass::Step2);
      }

      void Step2(int t, void*)
      {
        printf("Step 2\n");
        SetThink(t+1000, &JakasClass::Step1);
      }

      JakasClass()
      {
        SetThink(20, &JakasClass::Step1);
      }
    };
    */
    template <typename T>
    class Thinker
    {
    public:
      typedef void (T::*ThinkFunction)(int, void*);

      T* Object;
      uint32_t NextThink;
      ThinkFunction Think;
      void* Userdata;

      Thinker() : NextThink(0), Think(0), Userdata(0) { }

      void SetThink(uint32_t at, ThinkFunction func, T* object = 0)
      {
        NextThink = at;
        Think = func;
        Object = object;
      }

      void CheckThink(uint32_t currentTime)
      {
        ThinkFunction tf = Think;
        uint32_t thinkTime = NextThink;
        T* obj = Object;
        if (!obj)
          obj = (T*)this;

        if (tf && thinkTime && currentTime >= thinkTime)
        {
          NextThink = 0;
          (*obj.*tf)(currentTime, Userdata);
        }
      }
    };
    
  }
}

#endif